#pragma once

#include <gexpl_gpio.h>

// 将给定GPIO的若干位置1（列于参数中，16位分别对应16个引脚）。
// 对于输出引脚是输出高电平，对于上下拉输入引脚是设置上拉。
static inline void gpio_output_pull_high(gpio_qe gpio_q, gpio_pins_s pins) {
	gpio_bop_expl_s bop = {
		.high_pins = pins,
	};
	gpio_output_pull_high_low(gpio_q, bop);
}

// 对给定位的mask值和欲设置的引脚值，计算该位对应的BOP。
static inline u32_s gpio_sl(u32_s mask_bit, u32_s pin_bit, u32_s pin_no) {
	// 该变量在将给定位置0时为16，置1时为0。
	u32_s left_0_16 = (!pin_bit) << 4;
	// 若该位被mask，则将BOP中相应位置位，否则不置位。
	// 该位置0时左移16位，否则左移0位。
	u32_s t = mask_bit << left_0_16;
	return t << pin_no;
}

// 将给定GPIO的给定引脚设为给定电平值（或上下拉）
static inline void gpio_set_one_output_pull_pin(gpio_qe gpio_q, u32_s pin,
						u32_s value) {
	u32_s bop = gpio_sl(1, value, pin);
	gpio_wreg_bop(gpio_q, bop);
}

// 设置部分引脚值时使用的数据结构，mask为1的引脚设为pins对应位，其余引脚不变。
typedef struct {
	gpio_pins_s mask;
	gpio_pins_s pins;
} mask_pins_s;

// 将给定GPIO的若干位设为给定值，参数含义如上数据结构。
static inline void gpio_mask_set_pins(gpio_qe gpio_q, mask_pins_s mask_pins) {
	gpio_pins_s mask = mask_pins.mask;
	gpio_pins_s pins = mask_pins.pins;
	u32_s bop = 0;
	bop |= gpio_sl(mask.PIN0, pins.PIN0, 0);
	bop |= gpio_sl(mask.PIN1, pins.PIN1, 1);
	bop |= gpio_sl(mask.PIN2, pins.PIN2, 2);
	bop |= gpio_sl(mask.PIN3, pins.PIN3, 3);
	bop |= gpio_sl(mask.PIN4, pins.PIN4, 4);
	bop |= gpio_sl(mask.PIN5, pins.PIN5, 5);
	bop |= gpio_sl(mask.PIN6, pins.PIN6, 6);
	bop |= gpio_sl(mask.PIN7, pins.PIN7, 7);
	bop |= gpio_sl(mask.PIN8, pins.PIN8, 8);
	bop |= gpio_sl(mask.PIN9, pins.PIN9, 9);
	bop |= gpio_sl(mask.PIN10, pins.PIN10, 10);
	bop |= gpio_sl(mask.PIN11, pins.PIN11, 11);
	bop |= gpio_sl(mask.PIN12, pins.PIN12, 12);
	bop |= gpio_sl(mask.PIN13, pins.PIN13, 13);
	bop |= gpio_sl(mask.PIN14, pins.PIN14, 14);
	bop |= gpio_sl(mask.PIN15, pins.PIN15, 15);
	gpio_wreg_bop(gpio_q, bop);
}
